package com.example.hystrixDemo.service.impl;

import com.example.hystrixDemo.service.LoanService;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.annotation.ObservableExecutionMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import rx.Observable;
import rx.Subscriber;

/**
 * @Deacription TODO
 * @Author baohuajie
 * @Date 2020/9/7 15:05
 * @Version 1.0
 **/
@Component
public class LoanServiceImpl implements LoanService {
    Logger logger = LoggerFactory.getLogger(LoanServiceImpl.class);

    @Override
    @HystrixCommand(fallbackMethod = "queryLoanResultFallback"
            , commandKey = "loanQueryResult"
            , groupKey = "loans"
            , threadPoolKey = "loansThreadPool"
            , commandProperties = {
            @HystrixProperty(name = "execution.timeout.enabled", value = "true")
    }
            , threadPoolProperties = {  @HystrixProperty(name = "coreSize", value ="2"),
                                        @HystrixProperty(name = "maximumSize", value = "4"),
                                        @HystrixProperty(name = "maxQueueSize", value = "4"),
                                        @HystrixProperty(name = "queueSizeRejectionThreshold", value = "4"),
                                        @HystrixProperty(name = "keepAliveTimeMinutes", value = "5")

                                        }
    )
    public String queryLoanResult() throws InterruptedException {
        logger.info("========queryLoanResult=====>start,当前线程:{}", Thread.currentThread().getName());
        Thread.sleep(5000);
        String result = "success";
        logger.info("========queryLoanResult=====>end");
        return result;
    }

    /**
     * 使用信号量隔离
     * @return
     * @throws Exception
     */
    @HystrixCommand(groupKey = "queryLoanResult2GroupKey"
            , commandKey = "queryLoanResult2Key"
            , fallbackMethod = "queryLoanResult2Fallback"
            , commandProperties = {
                    @HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
                    @HystrixProperty(name = "execution.timeout.enabled", value = "true"),
                    @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "3000"),
                    @HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "20")

            }
    )
    @Override
    public String queryLoanResult2() throws Exception {
        logger.info("========queryLoanResult2=====>start,当前线程:{}", Thread.currentThread().getName());
        Thread.sleep(5000);
        logger.info("========queryLoanResult2=====>end,当前线程:{}", Thread.currentThread().getName());
        return "succes";
    }

    /**
     *  EAGER参数表示使用observe()方式执行
     */
    @HystrixCommand(observableExecutionMode = ObservableExecutionMode.EAGER
            , fallbackMethod = "queryLoanResult1Fallback"
            , commandKey = "queryLoanResult1"
            , commandProperties = {
                @HystrixProperty(name = "execution.timeout.enabled", value = "true")
            })
    @Override
    public Observable<String> queryLoanResult1() throws InterruptedException {
        return Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {

                if (!subscriber.isUnsubscribed()) {
                    subscriber.onNext("张三的ID:");
                    subscriber.onNext("张三的ID1:");
                    subscriber.onNext("张三的ID2:");
//                    int i = 1 / 0; //抛异常，模拟服务降级
                    subscriber.onCompleted();
                }


            }
        });
    }



    /**
     * 失败回调
     *
     * @return
     */
    private String queryLoanResultFallback() {
        return "queryLoanResultFallback";
    }


    /**
     * 失败回调
     *
     * @return
     */
    private String queryLoanResult1Fallback() {
        return "queryLoanResult1Fallback";
    }
    /**
     * 失败回调
     *
     * @return
     */
    private String queryLoanResult2Fallback() {
        logger.info("========queryLoanResult2Fallback=====当前线程:{}", Thread.currentThread().getName());
        return "queryLoanResult2Fallback";
    }
}
